package org.snare.alumni.modules.app;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.snare.alumni.modules.admin.card.dto.CardDTO;
import org.snare.alumni.modules.admin.card.dto.CardSameVO;
import org.snare.alumni.modules.admin.card.entity.CardEntity;
import org.snare.alumni.modules.admin.card.mapper.CardMapper;
import org.snare.alumni.modules.admin.card.service.api.CardService;
import org.snare.alumni.modules.admin.student.entity.StudentEntity;
import org.snare.alumni.modules.admin.student.mapper.StudentMapper;
import org.snare.community.modules.admin.account.dto.AccountInfo;
import org.snare.community.modules.admin.account.service.api.SnsAccountService;
import org.snare.spider.cobweb.common.constant.BaseConstant;
import org.snare.spider.cobweb.crm.user.entity.CrmUserEntity;
import org.snare.spider.cobweb.crm.user.mapper.CrmUserMapper;
import org.snare.spider.cobweb.oss.dto.FileUploadDTO;
import org.snare.spider.common.exception.BusinessException;
import org.snare.spider.common.utils.BeanUtils;
import org.snare.spider.toolkit.jwt.JwtUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "校园卡")
@RequestMapping("/alumni/app/card")
@RestController
@RequiredArgsConstructor
public class CardController {

    private final CardService cardService;

    private final CardMapper cardMapper;

    private final StudentMapper studentMapper;

    private final CrmUserMapper userMapper;

    private final SnsAccountService snsAccountService;

    @Transactional
    @PostMapping("/apply")
    @ApiOperation(value = "申请", httpMethod = "POST")
    public void apply(@RequestBody @Valid CardDTO cardDTO) {
        if (CollectionUtils.isEmpty(cardDTO.getStudentList())) {
            throw new BusinessException("请完善毕业信息");
        }
        Set<String> collect = cardDTO.getStudentList().stream().map(StudentEntity::getName).collect(Collectors.toSet());
        if (collect.size() > 1) {
            throw new BusinessException("存在不同姓名的毕业信息，请重新选择");
        }
        String uid = JwtUtils.getUid();
        cardDTO.setUid(uid);
        for (StudentEntity student : cardDTO.getStudentList()) {
            // 根据姓名匹配到信息，更新
            if (ObjectUtils.isNotEmpty(student.getId())) {
                // 更新同学录
                new LambdaUpdateChainWrapper<>(studentMapper)
                        .set(StudentEntity::getUid, uid).eq(StudentEntity::getId, student.getId())
                        .update();
            } else {
                // 新增同学录
                student.setUid(uid);
                studentMapper.insert(student);
            }
        }

        //  更新校友卡状态
        CardEntity cardEntity = BeanUtils.copy(cardDTO, CardEntity.class);
        if (CollectionUtils.isNotEmpty(cardDTO.getImgList())) {
            cardEntity.setImages(JSON.toJSONString(cardDTO.getImgList()));
            cardEntity.setAvatar(cardDTO.getImgList().get(0).getPreviewUrl());
        }
        cardEntity.setStatus("2");
        cardMapper.insert(cardEntity);

        // 圈子账户
        AccountInfo accountInfo = new AccountInfo();
        accountInfo.setNickname(cardDTO.getName());
        accountInfo.setUid(uid);
        accountInfo.setStatus(BaseConstant.YES);
        accountInfo.setAvatar(cardEntity.getAvatar());
        snsAccountService.add(accountInfo);

        new LambdaUpdateChainWrapper<>(userMapper)
                .set(CrmUserEntity::getRealName, cardDTO.getName())
                .eq(CrmUserEntity::getId, uid)
                .update();
    }

    @Transactional
    @PostMapping("/edit")
    @ApiOperation(value = "更新", httpMethod = "POST")
    public void edit(@RequestBody @Valid CardDTO cardDTO) {
        String uid = JwtUtils.getUid();
        if (!Objects.equals(uid, cardDTO.getUid())) {
            throw new BusinessException("无权操作");
        }
        cardService.edit(cardDTO);
    }


    @GetMapping("/info")
    @ApiOperation(value = "详情", httpMethod = "GET")
    CardDTO info() {
        String uid = JwtUtils.getUid();
        CardDTO cardDTO = cardService.detail(null, uid);
        if (cardDTO != null) {
            cardDTO.setImgList(JSON.parseArray(cardDTO.getImages(), FileUploadDTO.class));
            cardDTO.setStudentList(new LambdaQueryChainWrapper<>(studentMapper)
                    .eq(StudentEntity::getUid, uid).orderByDesc(StudentEntity::getGraduationYear).list());
        }
        return cardDTO;
    }

    @GetMapping("/same")
    @ApiOperation(value = "同班同学", httpMethod = "GET")
    List<CardSameVO> same(String position) {
        String uid = JwtUtils.getUid();
        return cardService.sameClass(position, uid);
    }

    @GetMapping("/updateCoordinate")
    @ApiOperation(value = "更新定位", httpMethod = "GET")
    void updateCoordinate(@RequestParam float longitude, @RequestParam float latitude) {
        String uid = JwtUtils.getUid();
        new LambdaUpdateChainWrapper<>(cardMapper)
                .set(CardEntity::getCoordinate, longitude + "," + latitude)
                .eq(CardEntity::getUid, uid).update();
    }

    @GetMapping("/getLocationCard")
    @ApiOperation(value = "获取定位校友", httpMethod = "GET")
    List<CardDTO> getLocationCard() {
        MPJLambdaWrapper<CardEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(CardEntity.class)
                .selectAll(CrmUserEntity.class)
                .leftJoin(CrmUserEntity.class, CrmUserEntity::getId, CardEntity::getUid)
                .eq(CardEntity::getStatus, "2")
                .and(w -> w.isNotNull(CardEntity::getCoordinate).or().ne(CardEntity::getCoordinate, ""));
        return cardMapper.selectJoinList(CardDTO.class, wrapper);
    }


    @GetMapping("/getCount")
    @ApiOperation(value = "数量查询", httpMethod = "GET")
    List<Map<String, Object>> getCount() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>();
        map1.put("title", "总人数");
        map1.put("count", cardMapper.selectCount(null));
        map1.put("icon", "el-icon-user-solid");
        map1.put("color", "rgb(49, 180, 141)");
//        map1.put("href", "https://avuejs.com");
//        map1.put("target", "_blank");
        list.add(map1);

        Map<String, Object> map2 = new HashMap<>();
        map2.put("title", "已申请");
        map2.put("count", new LambdaQueryChainWrapper<>(cardMapper).eq(CardEntity::getStatus, "2").count());
        map2.put("icon", "el-icon-postcard");
        map2.put("color", "rgb(56, 161, 242)");
//        map2.put("href", "https://avuejs.com");
//        map2.put("target", "_blank");
        list.add(map2);

        Map<String, Object> map3 = new HashMap<>();
        map3.put("title", "审核中");
        map3.put("count", new LambdaQueryChainWrapper<>(cardMapper).eq(CardEntity::getStatus, "1").count());
        map3.put("icon", "el-icon-setting");
        map3.put("color", "rgb(117, 56, 199)");
//        map3.put("href", "https://avuejs.com");
//        map3.put("target", "_blank");
        list.add(map3);

        Map<String, Object> map4 = new HashMap<>();
        map4.put("title", "未通过");
        map4.put("count", new LambdaQueryChainWrapper<>(cardMapper).eq(CardEntity::getStatus, "-1").count());
        map4.put("icon", "el-icon-setting");
        map4.put("color", "rgb(230, 71, 88)");
//        map4.put("href", "https://avuejs.com");
//        map4.put("target", "_blank");
        list.add(map4);

        return list;
    }

}
